package com.example.audio_test.utils

import android.media.MediaCodec
import android.media.MediaFormat
import android.media.MediaMuxer
import java.io.File
import java.io.IOException
import java.lang.Exception
import java.lang.IllegalStateException
import java.lang.RuntimeException
import java.nio.ByteBuffer

/**
 *mp4混合器
 *
 * @author : Kun
 * @date : 2021/6/29
 * @time : 10:07
 */
class MediaMuxerUtil(private val mFilePath: String, private val durationMillis: Long) {

    private var mMuxer: MediaMuxer? = null
    private var index = 0
    private var mVideoTrackIndex = -1
    private var mAudioTrackIndex = -1
    private var mBeginMillis = 0L
    private var mVideoFormat: MediaFormat? = null
    private var mAudioFormat: MediaFormat? = null

    init {
        try {
            mMuxer = MediaMuxer(mFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
            mMuxer!!.setOrientationHint(90)
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    @Synchronized
    fun addTrack(format: MediaFormat, isVideo: Boolean) {
        if (mAudioTrackIndex != -1 && mVideoTrackIndex != -1) {
//            throw RuntimeException("already add all tracks")
        return
        }

        val track = mMuxer!!.addTrack(format)
        if (isVideo) {
            mVideoFormat = format
            mVideoTrackIndex = track
            if (mAudioTrackIndex != -1) {
                mMuxer!!.start()
                mBeginMillis = System.currentTimeMillis()
            }
        } else {
            mAudioFormat = format
            mAudioTrackIndex = track
            if (mVideoTrackIndex != -1) {
                mMuxer!!.start()
                mBeginMillis = System.currentTimeMillis()
            }
        }
    }

    /**
     * 合并音视频流
     */
    @Synchronized
    fun pumpStream(outputBuffer: ByteBuffer, bufferInfo: MediaCodec.BufferInfo, isVideo: Boolean) {
        if (mAudioTrackIndex == -1 || mVideoTrackIndex == -1) {
            return;
        }
        if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG != 0) {
            //忽略
        } else if (bufferInfo.size != 0) {
            if (isVideo && mVideoTrackIndex == -1) {
                throw RuntimeException("muxer hasn't started")
            }

            outputBuffer.position(bufferInfo.offset)
            outputBuffer.limit(bufferInfo.offset + bufferInfo.size)

            mMuxer!!.writeSampleData(
                if (isVideo) mVideoTrackIndex else mAudioTrackIndex,
                outputBuffer,
                bufferInfo
            )
        }

        if (System.currentTimeMillis() - mBeginMillis >= durationMillis) {
            //时间达到最大长度,新开一个文件
            mMuxer!!.stop()
            mMuxer!!.release()
            mMuxer = null
            mAudioTrackIndex = -1
            mVideoTrackIndex = -1

            try {
                mMuxer = MediaMuxer(
                    mFilePath + '-' + ++index + ".mp4",
                    MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4
                )
                addTrack(mAudioFormat!!, false)
                addTrack(mVideoFormat!!, true)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    @Synchronized
    fun release() {
        if (mMuxer != null) {
            if (mAudioTrackIndex != -1 && mVideoTrackIndex != -1) {

                try {
                    mMuxer!!.stop()
                    mMuxer!!.release()
                } catch (e: IllegalStateException) {
                    e.printStackTrace()
                }
                if (System.currentTimeMillis() - mBeginMillis <= 1500) {
                    //删除较短的视频
                    File(mFilePath + "-" + index + ".mp4").delete()
                }
                mVideoTrackIndex = -1
                mAudioTrackIndex = -1
            }
        }
    }
}